"""业务异常类定义"""
from typing import Any, Optional
from app.exception.error_code import ErrorCode, error_code_to_http_status


class CodeException(Exception):
    """带错误码的业务异常类"""
    
    def __init__(self, code: int, err_msg: str, data: Any = None, status_code: Optional[int] = None):
        """
        初始化业务异常
        
        Args:
            code: 错误码
            err_msg: 错误消息
            data: 附加数据，默认为None
            status_code: HTTP状态码，不指定时根据错误码自动映射
        """
        self.code = code
        self.err_msg = err_msg
        self.data = data
        # 如果未指定状态码，则从映射中获取
        self.status_code = status_code or error_code_to_http_status.get(code, 400)
        super().__init__(f"Error {code}: {err_msg}")
    
    # =============================================================================
    # 认证相关异常
    # =============================================================================
    @classmethod
    def no_login(cls, err_msg: str = "用户未登录") -> 'CodeException':
        """创建未登录异常"""
        # 向后兼容旧的错误码
        return cls(ErrorCode.AUTH_FAILED, err_msg)
    
    @classmethod
    def auth_failed(cls, err_msg: str = "认证失败") -> 'CodeException':
        """创建认证失败异常"""
        return cls(ErrorCode.AUTH_FAILED, err_msg, status_code=401)
    
    @classmethod
    def token_illegal(cls, err_msg: str = "Token已过期或无效") -> 'CodeException':
        """创建Token非法异常"""
        # 向后兼容旧的错误码
        return cls(ErrorCode.TOKEN_INVALID, err_msg, status_code=401)
    
    @classmethod
    def token_invalid(cls, err_msg: str = "令牌无效") -> 'CodeException':
        """创建令牌无效异常"""
        return cls(ErrorCode.TOKEN_INVALID, err_msg, status_code=401)
    
    @classmethod
    def token_expired(cls, err_msg: str = "令牌已过期") -> 'CodeException':
        """创建令牌过期异常"""
        return cls(ErrorCode.TOKEN_EXPIRED, err_msg, status_code=401)
    
    @classmethod
    def not_permission(cls, err_msg: str = "无操作权限") -> 'CodeException':
        """创建无权限异常"""
        # 向后兼容旧的错误码
        return cls(ErrorCode.NO_PERMISSION, err_msg, status_code=403)
    
    # =============================================================================
    # 参数相关异常
    # =============================================================================
    @classmethod
    def invalid_param(cls, err_msg: str = "无效的参数") -> 'CodeException':
        """创建参数无效异常"""
        return cls(ErrorCode.INVALID_PARAMS, err_msg)
    
    @classmethod
    def validation_error(cls, err_msg: str = "参数验证失败") -> 'CodeException':
        """创建参数验证异常"""
        return cls(ErrorCode.INVAILD_PARAM_EXCEPTION, err_msg, status_code=422)
    
    @classmethod
    def missing_param(cls, param_name: str) -> 'CodeException':
        """创建缺少参数异常"""
        return cls(ErrorCode.MISSING_REQUIRED_PARAMS, f"缺少必要参数: {param_name}")
    
    # =============================================================================
    # 资源相关异常
    # =============================================================================
    @classmethod
    def entity_exist(cls, err_msg: str = "实体已存在") -> 'CodeException':
        """创建实体已存在异常"""
        return cls(ErrorCode.RESOURCE_ALREADY_EXISTS, err_msg, status_code=409)
    
    @classmethod
    def resource_not_found(cls, err_msg: str = "资源不存在") -> 'CodeException':
        """创建资源未找到异常"""
        return cls(ErrorCode.RESOURCE_NOT_FOUND, err_msg, status_code=404)
    
    # =============================================================================
    # 业务逻辑异常
    # =============================================================================
    @classmethod
    def business_error(cls, err_msg: str, code: int = ErrorCode.BUSINESS_ERROR) -> 'CodeException':
        """创建业务错误异常"""
        return cls(code, err_msg)
    
    @classmethod
    def operation_failed(cls, err_msg: str = "操作失败") -> 'CodeException':
        """创建操作失败异常"""
        return cls(ErrorCode.OPERATION_FAILED, err_msg)
    
    @classmethod
    def sys_error(cls, err_msg: str) -> 'CodeException':
        """创建系统提示异常"""
        # 向后兼容旧的错误码
        return cls(ErrorCode.SYSTEM_ERROR, err_msg)
    
    # =============================================================================
    # 数据库相关异常
    # =============================================================================
    @classmethod
    def database_error(cls, err_msg: str = "数据库操作失败") -> 'CodeException':
        """创建数据库错误异常"""
        return cls(ErrorCode.DATABASE_ERROR, err_msg, status_code=500)
    
    @classmethod
    def with_data(cls, code: int, err_msg: str, data: Any) -> 'CodeException':
        """创建带附加数据的异常
        
        Args:
            code: 错误码
            err_msg: 错误消息
            data: 附加数据
            
        Returns:
            CodeException实例
        """
        return cls(code, err_msg, data=data)